package com.xiaoxu.intranetweb.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HTTP;

import java.io.IOException;
import java.io.Serializable;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @Description: 网络请求工具类--Powered by Apache HttpClient
 * @Author: junqiang.lu
 * @Date: 2019/5/16
 */
public class SimpleHttpClientUtil implements Serializable {

    private static final long serialVersionUID = 4634161754990919271L;

    private static volatile HttpClient httpClient;

    private SimpleHttpClientUtil(){}


    /**
     * GET 方式请求
     * 参数通过 url 拼接
     *
     * @param host 请求地址
     * @param path 接口路径
     * @param paramsMap 请求参数
     * @return
     * @throws IOException
     */
    public static HttpResponse doGet(String host, String path, Map<String, String> paramsMap) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(10000)
                .setConnectTimeout(5000)
                .build();
        HttpGet httpGet = new HttpGet(getRequestUrl(host, path, paramsMap));
        httpGet.setConfig(requestConfig);
        httpGet.setHeader(HTTP.CONTENT_TYPE,ContentType.create(ContentType.APPLICATION_FORM_URLENCODED
                .getMimeType(),Consts.UTF_8).toString());
        return httpClient.execute(httpGet);
    }

    /**
     * POST 方式请求
     * 参数通过 Body 传送,JSON 格式
     *
     * @param host 请求地址
     * @param path 接口路径
     * @param jsonParams 请求参数(json 字符串)
     * @return
     */
    public static HttpResponse doPost(String host, String path, JSONObject jsonParams) throws IOException {
        initHttpClient();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(5000)
                .setConnectTimeout(5000)
                .setRedirectsEnabled(false)
                .build();
        HttpPost httpPost = new HttpPost(host + path);
//        StringEntity stringentity = new StringEntity(jsonParams, ContentType.APPLICATION_JSON);
        StringEntity stringentity = new StringEntity(jsonParams.toJSONString(), ContentType.APPLICATION_JSON);
        httpPost.setEntity(stringentity);
        httpPost.setConfig(requestConfig);
        httpPost.addHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
        return httpClient.execute(httpPost);
    }


    public static HttpResponse doPostWithXml(String path, String xmlData) throws IOException {
        // 初始化 HttpClient
        initHttpClient();

        // 配置请求参数
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(5000)
                .setConnectTimeout(5000)
                .setRedirectsEnabled(false)
                .build();

        // 创建 HttpPost 请求
        HttpPost httpPost = new HttpPost(path);

        // 设置请求体为 XML 数据
        StringEntity stringEntity = new StringEntity(xmlData, ContentType.APPLICATION_XML);
        httpPost.setEntity(stringEntity);

        // 设置请求配置
        httpPost.setConfig(requestConfig);

        // 添加请求头，指定 Content-Type 为 XML
        httpPost.addHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_XML.toString());

        // 执行请求并返回响应
        return httpClient.execute(httpPost);
    }

    /**
     * 初始化 httpClient
     * @return
     */
    public static void initHttpClient() {
        if (httpClient == null) {
            PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
            cm.setMaxTotal(200); // 增加最大连接数
            cm.setDefaultMaxPerRoute(40); // 增加每个路由的最大连接数

            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectionRequestTimeout(60000) // 增加连接请求的超时时间
                    .build();

            httpClient = HttpClients.custom()
                    .setDefaultRequestConfig(requestConfig)
                    .setConnectionManager(cm)
                    .build();
        }
    }
    /**
     * 获取完整请求地址(包含参数)
     * 参数拼接在 url 中
     *
     * @param host 请求地址
     * @param path 接口路径
     * @param params 请求参数
     * @return
     */
    private static String getRequestUrl(String host, String path, Map<String, String> params) throws IOException {
        StringBuilder urlBuilder = new StringBuilder(host);
        urlBuilder.append(path);
        if (params != null && !params.isEmpty()) {
            urlBuilder.append("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                String name = entry.getKey();
                String value = entry.getValue();
                urlBuilder.append(URLEncoder.encode(name, String.valueOf(StandardCharsets.UTF_8)));
                urlBuilder.append("=");
                urlBuilder.append(URLEncoder.encode(value, String.valueOf(StandardCharsets.UTF_8)));
                urlBuilder.append("&");
            }
            urlBuilder.deleteCharAt(urlBuilder.length() - 1); // 移除最后一个"&"字符
        }
        return urlBuilder.toString();
    }

}
